/**
    ATClab - scriptable Air Traffic Control simulations.
    Copyright (C) 2010 openatclab@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/

#ifndef __ATC_AIRCRAFT_DATA_HDR__
#define __ATC_AIRCRAFT_DATA_HDR__

#define AIRCRAFT_PATH_TOKENS std::deque< AircraftPathToken* >
#define STATE_QUEUE          std::deque< const AircraftState* >


#include "atc.h"
#include "atc_types.h"
#include <deque>


namespace atc {

	//
	// atc::AircraftData
	//

	struct AircraftData {

		AircraftData( ) : call( 0 ), type( 0 ) {}

		AircraftData( const AircraftData &rhs )
			  : call( rhs.call ), type( rhs.type ) {}

		const char *call;
		const char *type;
	};


	//
	//
	// atc::AircraftPathToken
	//

	struct AircraftPathToken {

		AircraftPathToken(
				double X0, double Y0, double Z0, double V0
			  , double X1, double Y1, double Z1, double V1
		)
			  : x0( X0 ), y0( Y0 ), z0( Z0 ), v0( V0 )
			  , x1( X1 ), y1( Y1 ), z1( Z1 ), v1( V1 )
		{}

		AircraftPathToken( const AircraftPathToken &rhs )
			  : x0( rhs.x0 ), y0( rhs.y0 ), z0( rhs.z0 ), v0( rhs.v0 )
			  , x1( rhs.x1 ), y1( rhs.y1 ), z1( rhs.z1 ), v1( rhs.v1 )
		{}

		~AircraftPathToken() {}

		double x0, y0, z0, v0;
		double x1, y1, z1, v1;
	};


	//
	// atc::AircraftPath
	//

	class AircraftPath {

	public:
		typedef AIRCRAFT_PATH_TOKENS::const_iterator const_iterator;

	public:
		AircraftPath();
		AircraftPath( const AircraftPath & );
		~AircraftPath();

	public:
		void push( const AircraftPathToken & );
		bool is_valid() const;
		void next();
		bool done();

		const AircraftPathToken* data() const;

		AIRCRAFT_PATH_TOKENS::const_iterator begin() const;
		AIRCRAFT_PATH_TOKENS::const_iterator   end() const;

		Point future_point( const Point &, double ) const;
		void reroute( const AircraftPathToken *, const Point &, const Point & );

	private:
		Point future_point( const_iterator, const Point &, double s ) const;

	private:
		AIRCRAFT_PATH_TOKENS _plan;		// future
		//AIRCRAFT_PATH_TOKENS _track;	// past

	};

	//
	// atc::AircraftPath typedefs
	//
	typedef AIRCRAFT_PATH_TOKENS AircraftPathTokens;


	//
	// atc::ControlState
	//
	enum ControlState {
		   	CS_NONE			// black            >15mins from entry
		  , CS_ANNOUNCED	// blue             > 2mins from entry
		  , CS_PROPOSED		// blinking_orange	> 0mins from entry - can be accepted
		  , CS_ACCEPTED		// green			in sector/accepted
		  , CS_OVEROUT		// orange			< 2mins from exit  - can be handed off
		  , CS_HANDOFF		// white			for 30secs after hand off
		  , CS_NOMORE		// black
	};


	//
	// atc::AircraftState
	//

	/*!
	 *  UNITS:
	 *
	 *   x,  y : nautical miles
	 *       z : feet
	 *  dx, dy : knots (nautical miles per hour
	 *      dz : feet per minute
	 * 
	 *  ddx, ddy, ddz : ?????
	 *
	 *    cvel : knots
	 *    calt : feet
	 */

	struct AircraftState {
		AircraftState( 
				long tt, ControlState cs
			  ,	double X, double Y, double Z
			  , double B, double V
			  , double A, double C, double T
		)
			  : tag( tt )
			  , control( cs )
			  , x( X ), y( Y ), z( Z )
			  , heading( B )
			  , velocity( V )
			  , acceleration( A )
			  , climb_rate( C )
			  , throttle( T )
		{}

		AircraftState( const AircraftState& rhs ) 
			: tag( rhs.tag )
			, control( rhs.control )
			, x( rhs.x )
			, y( rhs.y )
			, z( rhs.z )
			, heading( rhs.heading )
			, velocity( rhs.velocity )
			, acceleration( rhs.acceleration )
			, climb_rate( rhs.climb_rate )
			, throttle( rhs.throttle )
		{}

		~AircraftState() {}

		long   tag;

		ControlState control;

		double x, y, z;
		double heading;
		double velocity;		// ground speed
		double acceleration;
		double climb_rate;
		double throttle;			// -1.0 < t < +1.0 throttle setting
	};


	//
	// atc::AircraftHistory
	//

	class AircraftHistory {

	public:
		AircraftHistory();
		~AircraftHistory();

	public:
		void add_event( const AircraftState * );

		typedef STATE_QUEUE::const_iterator const_iterator;

		AircraftHistory::const_iterator begin() const { 
			return _history.begin(); 
		}
		AircraftHistory::const_iterator end() const {
			return _history.end();
		}
		int size() const { return _history.size(); }

	private:
		STATE_QUEUE _history;
	};


};

#undef AIRCRAFT_PATH_TOKENS
#undef STATE_QUEUE

#endif
